package com.xqboss.apps.util.mh;

import com.alibaba.fastjson2.JSONObject;
import org.springframework.beans.BeanUtils;
import org.springframework.cglib.beans.BeanCopier;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author Administrator
 */
public class BeanCopierUtil extends BeanUtils {
    /**
     * BeanCopier的缓存
     */
    static final ConcurrentHashMap<String, BeanCopier> BEAN_COPIER_CACHE = new ConcurrentHashMap<>();

    /**
     * BeanCopier的copy
     *
     * @param source 源文件的
     * @param clazz  目标文件
     */
    public static <T> T copy(Object source, Class<T> clazz) {
        if (source == null) {
            return null;
        }

        String key = genKey(source.getClass(), clazz);
        BeanCopier beanCopier;
        if (BEAN_COPIER_CACHE.containsKey(key)) {
            beanCopier = BEAN_COPIER_CACHE.get(key);
        } else {
            beanCopier = BeanCopier.create(source.getClass(), clazz, false);
            BEAN_COPIER_CACHE.put(key, beanCopier);
        }
        T to = newInstance(clazz);
//		beanCopier.copy(source, to, null);
        BeanUtils.copyProperties(source, to);
        return to;
//		return BeanUtil.copy(source,clazz);
    }

    /**
     * 实例化对象
     *
     * @param <T>   泛型标记
     * @param clazz 类
     * @return 对象
     */
    @SuppressWarnings("unchecked")
    public static <T> T newInstance(Class<T> clazz) {
        return (T) instantiateClass(clazz);
    }

    /**
     * 批量拷贝
     *
     * @param sourcelist copyist
     * @param clazz      目标文件
     */
    public static <S, C> List<C> copylist(List<S> sourcelist, Class<C> clazz) {
        if (null == sourcelist) {
            return null;
        }
        List<C> list = new ArrayList<>(sourcelist.size());
        sourcelist.stream().forEach(source -> {
            list.add(copy(source, clazz));
        });
        return list;
    }


    /**
     * 生成key
     *
     * @param srcClazz 源文件的class
     * @param tgtClazz 目标文件的class
     * @return string
     */
    private static String genKey(Class<?> srcClazz, Class<?> tgtClazz) {
        return srcClazz.getName() + tgtClazz.getName();
    }


    /**
     * json拷贝单个bean
     */
    public static <T> T jsonCopy(Object source, Class<T> clazz) {
        return JSONObject.parseObject(JSONObject.toJSONString(source), clazz);
    }
}
